package com.itlong.cloud.operate.service.impl;

import com.google.zxing.BarcodeFormat;
import com.itlong.cloud.POJO.DTO.operate.*;
import com.itlong.cloud.POJO.PO.PaperImgPO;
import com.itlong.cloud.POJO.PO.PaperPO;
import com.itlong.cloud.POJO.VO.operate.OperatePaperGetVO;
import com.itlong.cloud.POJO.VO.operate.OperatePaperImgGetVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.enumerate.FileCatalogEnum;
import com.itlong.cloud.operate.dao.IOperatePaperDao;
import com.itlong.cloud.operate.dao.IOperatePaperImgDao;
import com.itlong.cloud.operate.service.IOperatePaperService;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.picture.LogoConfig;
import com.itlong.cloud.utils.picture.QrcodeUtils;
import com.itlong.cloud.utils.picture.VerifyCodeUtils;
import com.itlong.cloud.utils.random.LogicIdUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 *     运营-系统管理-说明书管理业务处理接口实现类
 * </desc>
 *
 * @createDate 2018/06/27
 */
@Service
@RefreshScope
public class OperatePaperServiceImpl implements IOperatePaperService {

    private static final Logger LOG = LoggerFactory.getLogger(OperatePaperServiceImpl.class);

    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;

    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;

    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;

    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;

    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;

    @Value("${" + PlatformConstants.PAPER_HTML_SERVERPATH + "}")
    public String PAPER_HTML_SERVERPATH;

    @Value("${" + PlatformConstants.PAPER_LOGO_SERVERPATH + "}")
    public String PAPER_LOGO_SERVERPATH;

    @Autowired
    private IOperatePaperDao iOperatePaperDao; // 说明书管理持久层对象
    @Autowired
    private IOperatePaperImgDao iOperatePaperImgDao;    // 说明书详情管理持久层对象

    /**
     * <desc>
     *      分页获取说明书信息
     * </desc>
     *
     * @param operatePaperGetPageDTO 说明书管理分页查询说明书数据传输对象
     * @return 分页查询结果对象
     * @author wangzhi
     * @createDate 2018/06/27
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<OperatePaperGetVO> getPapersByPage(OperatePaperGetPageDTO operatePaperGetPageDTO) throws Exception {
        // 将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(operatePaperGetPageDTO);
        Page<OperatePaperGetVO> page = new Page<>();
        page.getPage().setPageSize(operatePaperGetPageDTO.getPageSize());
        page.getPage().setCurrentPage(operatePaperGetPageDTO.getCurrentPage());
        params.put("startSlip", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        // 填充返回数据集
        List<OperatePaperGetVO> datas = iOperatePaperDao.getPapersByPage(params);
        page.setRows(datas,iOperatePaperDao.getPapersRecordCount(params));
        return page;
    }

    /**
     * <desc>
     *      精确查询单个说明书信息
     * </desc>
     *
     * @param operatePaperGetOneDTO 说明书管理单个精确查询说明书数据传输对象
     * @return 单个结果查询对象
     * @author wangzhi
     * @createDate 2018/06/28
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public OperatePaperGetVO getOnePaper(OperatePaperGetOneDTO operatePaperGetOneDTO) throws Exception {
        // 将DTO转换为Map params
        Map<String,Object> params = SqlUtil.convertBeanToMapParams(operatePaperGetOneDTO);
        return iOperatePaperDao.getOnePaper(params);
    }

    /**
     * <desc>
     *      保存说明书信息
     * </desc>
     *
     * @param operatePaperSaveDTO 说明书管理保存说明书数据传输对象
     * @return 受影响的行数
     * @throws Exception 不可预见性异常
     * @author wangzhi
     * @createDate 2018/06/28
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer savePaper(OperatePaperSaveDTO operatePaperSaveDTO) throws Exception {
//        LOG.error("【进入到非核心服务savePaper方法】");
        int intRes = 0;
        Date nowTime = new Date();
        PaperPO paperPO = new PaperPO();
        BeanUtils.copyProperties(operatePaperSaveDTO,paperPO);
        String paperId = LogicIdUtil.bussinessId();
        paperPO.setPaperId(paperId);
        paperPO.setStatus(DataStatusEnum.NORMAL.getType());
        paperPO.setCreateTime(nowTime);
        paperPO.setUpdateTime(nowTime);
        // 二维码的内容
        String htmlUrl = PAPER_HTML_SERVERPATH + "?id=" + paperPO.getPaperNumber();
        paperPO.setHtmlUrl(htmlUrl);
        // 生成二维码
        String qrcodeUrl = null;
        ByteArrayOutputStream os = new ByteArrayOutputStream();
//        LOG.error("【非核心服务savePaper方法】开始生成二维码");
        if (paperPO.getLogo() == 1){
            BufferedImage bim = QrcodeUtils.getQR_CODEBufferedImage(htmlUrl, BarcodeFormat.QR_CODE, 300, 300, QrcodeUtils.getDecodeHintType());

//            InputStream inputStream = new FileInputStream(PAPER_LOGO_SERVERPATH);
////            URL logoUrl = new URL(PAPER_LOGO_SERVERPATH);
////            HttpURLConnection httpURLConnection = (HttpURLConnection) logoUrl.openConnection();
////            httpURLConnection.setDoInput(true);
////            InputStream inputStream = httpURLConnection.getInputStream();
//            BufferedImage logoImage = ImageIO.read(inputStream);
            //将从服务器本地读取图片变更为从文件服务器读取
            byte[] bytes = VerifyCodeUtils.getFileStream(PAPER_LOGO_SERVERPATH,"");
            BufferedImage logoImage = ImageIO.read(new ByteArrayInputStream(bytes));
            BufferedImage bufferedImage = QrcodeUtils.addLogo_QRCode(bim, logoImage, "", new LogoConfig());
            ImageIO.write(bufferedImage, "jpg", os);
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(os.toByteArray());
            qrcodeUrl = this.uploadFile(byteArrayInputStream);
        } else {
            BufferedImage bim = QrcodeUtils.getQR_CODEBufferedImage(htmlUrl, BarcodeFormat.QR_CODE, 300, 300, QrcodeUtils.getDecodeHintType());
            ImageIO.write(bim, "jpg", os);
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(os.toByteArray());
            qrcodeUrl = this.uploadFile(byteArrayInputStream);
        }
//        LOG.error("【非核心服务savePaper方法】生成二维码结束");
        if (StringUtils.isBlank(qrcodeUrl)){
            return null;
        }
        paperPO.setQrcodeUrl(qrcodeUrl);
        // 保存说明书基本信息
//        LOG.error("【非核心服务savePaper方法】保存说明书基本信息");
        intRes += iOperatePaperDao.save(SqlUtil.durableData(paperPO,PlatformConstants.TABLE_SAVE));

//        List<Map<String,Object>> batchParams = new ArrayList<>();
        List<PaperImgPO> paperImgPOS = new ArrayList<>();
        List<OperatePaperImgSaveDTO> operatePaperImgSaveDTOS = operatePaperSaveDTO.getOperatePaperImgSaveDTOS();
        if (operatePaperImgSaveDTOS != null && !operatePaperImgSaveDTOS.isEmpty()){
//            LOG.error("【非核心服务savePaper方法】开始保存说明书详情信息");
            for (OperatePaperImgSaveDTO operatePaperImgSaveDTO : operatePaperImgSaveDTOS){
//                batchParams.clear();
                PaperImgPO paperImgPO = new PaperImgPO();
                paperImgPO.setPaperId(paperId);
                paperImgPO.setPaperUrl(operatePaperImgSaveDTO.getPaperUrl());
                paperImgPO.setShowOrder(operatePaperImgSaveDTO.getShowOrder());
                paperImgPO.setStatus(DataStatusEnum.NORMAL.getType());
                paperImgPO.setCreateTime(nowTime);
                paperImgPO.setUpdateTime(nowTime);
//                batchParams.add(SqlUtil.durableData(paperImgPO,PlatformConstants.TABLE_SAVE));
//                intRes += iOperatePaperImgDao.batchSave(batchParams);
                paperImgPOS.add(paperImgPO);
            }
            // 批量保存说明书详情信息
//            intRes += iOperatePaperImgDao.batchSave(batchParams);
            intRes += iOperatePaperImgDao.batchSavePaperImg(paperImgPOS);
        }

        return intRes;
    }

    /**
     * <desc>
     *      修改说明书信息
     * </desc>
     *
     * @param operatePaperUpdateDTO 说明书管理修改说明书数据传输对象
     * @return 受影响的行数
     * @author wangzhi
     * @createDate 2018/06/29
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer updatePaper(OperatePaperUpdateDTO operatePaperUpdateDTO) throws Exception {
        int intRes = 0;
        Date nowTime = new Date();
        PaperPO paperPO = new PaperPO();
        BeanUtils.copyProperties(operatePaperUpdateDTO,paperPO);
        paperPO.setUpdateTime(nowTime);
        // 二维码的内容
        String htmlUrl = PAPER_HTML_SERVERPATH + "?id=" + paperPO.getPaperNumber();
        paperPO.setHtmlUrl(htmlUrl);
        // 生成二维码
        String qrcodeUrl = null;
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        if (paperPO.getLogo() == 1){
            BufferedImage bim = QrcodeUtils.getQR_CODEBufferedImage(htmlUrl, BarcodeFormat.QR_CODE, 300, 300, QrcodeUtils.getDecodeHintType());

            byte[] bytes = VerifyCodeUtils.getFileStream(PAPER_LOGO_SERVERPATH,"");
            BufferedImage logoImage = ImageIO.read(new ByteArrayInputStream(bytes));

            BufferedImage bufferedImage = QrcodeUtils.addLogo_QRCode(bim, logoImage, "", new LogoConfig());
            ImageIO.write(bufferedImage, "jpg", os);
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(os.toByteArray());
            qrcodeUrl = this.uploadFile(byteArrayInputStream);
        } else {
            BufferedImage bim = QrcodeUtils.getQR_CODEBufferedImage(htmlUrl, BarcodeFormat.QR_CODE, 300, 300, QrcodeUtils.getDecodeHintType());
            ImageIO.write(bim, "jpg", os);
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(os.toByteArray());
            qrcodeUrl = this.uploadFile(byteArrayInputStream);
        }
        if (StringUtils.isBlank(qrcodeUrl)){
            return null;
        }
        paperPO.setQrcodeUrl(qrcodeUrl);
        intRes += iOperatePaperDao.update(SqlUtil.durableData(paperPO,PlatformConstants.TABLE_UPDATE));
        return intRes;
    }

    /**
     * <desc>
     *      删除说明书信息
     * </desc>
     *
     * @param paperId 说明书id
     * @return 受影响的行数
     * @author wangzhi
     * @createDate 2018/06/29
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer deletePaper(String paperId) throws Exception {
        int intRes = 0;
        intRes += iOperatePaperDao.deletePaper(paperId);
        PaperImgPO paperImgPO = new PaperImgPO();
        paperImgPO.setPaperId(paperId);
        intRes += iOperatePaperImgDao.deletePaperImg(SqlUtil.convertBeanToMapParams(paperImgPO));
        return intRes;
    }

    /**
     * <desc>
     *      查看说明书详情
     * </desc>
     *
     * @param operatePaperImgGetDTO 查询参数
     * @return 获取说明书详情信息VO
     * @author wangzhi
     * @createDate 2018/07/02
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public OperatePaperImgGetVO getPaperImg(OperatePaperImgGetDTO operatePaperImgGetDTO) throws Exception {
        OperatePaperImgGetVO operatePaperImgGetVO = iOperatePaperImgDao.getPaperImg(SqlUtil.convertBeanToMapParams(operatePaperImgGetDTO));
        if (operatePaperImgGetVO == null) {
            operatePaperImgGetVO = new OperatePaperImgGetVO();
            OperatePaperGetVO operatePaperGetVO = iOperatePaperDao.getOnePaper(SqlUtil.convertBeanToMapParams(operatePaperImgGetDTO));
            BeanUtils.copyProperties(operatePaperGetVO,operatePaperImgGetVO);
            return operatePaperImgGetVO;
        }
        return operatePaperImgGetVO;
    }

    /**
     * <desc>
     *      添加说明书详情
     * </desc>
     *
     * @param operatePaperImgSaveOrUpdateDTO 添加数据参数
     * @return 受影响的行数
     * @author wangzhi
     * @createDate 2018/07/02
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer savePaperImg(OperatePaperImgSaveOrUpdateDTO operatePaperImgSaveOrUpdateDTO) throws Exception {
        int intRes = 0;
        Date nowTime = new Date();
        String paperId = operatePaperImgSaveOrUpdateDTO.getPaperId();
//        List<Map<String,Object>> batchParams = new ArrayList<>();
        List<PaperImgPO> paperImgPOS = new ArrayList<>();
        List<OperatePaperImgSaveDTO> operatePaperImgSaveDTOS = operatePaperImgSaveOrUpdateDTO.getOperatePaperImgSaveDTOS();
        if (operatePaperImgSaveDTOS != null && !operatePaperImgSaveDTOS.isEmpty()){
            for (OperatePaperImgSaveDTO operatePaperImgSaveDTO : operatePaperImgSaveDTOS){
                PaperImgPO paperImgPO = new PaperImgPO();
                paperImgPO.setPaperId(paperId);
                paperImgPO.setPaperUrl(operatePaperImgSaveDTO.getPaperUrl());
                paperImgPO.setShowOrder(operatePaperImgSaveDTO.getShowOrder());
                paperImgPO.setStatus(DataStatusEnum.NORMAL.getType());
                paperImgPO.setCreateTime(nowTime);
                paperImgPO.setUpdateTime(nowTime);
//                batchParams.add(SqlUtil.durableData(paperImgPO,PlatformConstants.TABLE_SAVE));
                paperImgPOS.add(paperImgPO);
            }
        }
//        intRes += iOperatePaperImgDao.batchSave(batchParams);
        intRes += iOperatePaperImgDao.batchSavePaperImg(paperImgPOS);
        return intRes;
    }

    /**
     * <desc>
     *      编辑(替换)说明书详情图片
     * </desc>
     *
     * @param operatePaperImgSaveOrUpdateDTO 修改数据参数
     * @return 受影响的行数
     * @author wangzhi
     * @createDate 2018/07/02
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer updatePaperImg(OperatePaperImgSaveOrUpdateDTO operatePaperImgSaveOrUpdateDTO) throws Exception {
        int intRes = 0;
        Date nowTime = new Date();
        Integer id = operatePaperImgSaveOrUpdateDTO.getId();
        PaperImgPO paperImgPO = new PaperImgPO();
        OperatePaperImgSaveDTO operatePaperImgSaveDTO = operatePaperImgSaveOrUpdateDTO.getOperatePaperImgSaveDTOS().get(0);
        paperImgPO.setId(id);
        paperImgPO.setPaperUrl(operatePaperImgSaveDTO.getPaperUrl());
        paperImgPO.setShowOrder(operatePaperImgSaveDTO.getShowOrder());
        paperImgPO.setUpdateTime(nowTime);
        intRes += iOperatePaperImgDao.updatePaperImg(paperImgPO);
        return intRes;
    }

    /**
     * <desc>
     *      删除说明书详情
     * </desc>
     *
     * @param operatePaperImgDeleteDTO 删除说明书详情数据传输对象
     * @return 受影响的行数
     * @throws Exception
     * @author wangzhi
     * @createDate 2018/07/02
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer deletePaperImg(OperatePaperImgDeleteDTO operatePaperImgDeleteDTO) throws Exception {
        return iOperatePaperImgDao.deletePaperImg(SqlUtil.convertBeanToMapParams(operatePaperImgDeleteDTO));
    }

    /**
     * <desc>
     *      Ftp上传文件，返回Url.
     * </desc>
     *
     * @param inputStream 文件流
     * @return 文件上传成功后会返回Url,否则返回空
     * @author wangzhi
     * @createDate 2018/06/28
     */
    private String uploadFile(InputStream inputStream) throws IOException {
        String fileUrl = "";
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                inputStream,
                "jpg",
                FILE_ACCESS_URL,
                FileCatalogEnum.OPERATE_PAPER_QR_CODE_FILE.getType()
        );
        Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
        Boolean returnCode = (Boolean)resultMap.get("returnCode");
        if (returnCode == false){
            return fileUrl;
        }
        fileUrl = resultMap.get("accessPath").toString();
        return fileUrl;
    }
}
